#pragma once

#include "localsocket.hpp"
#include "localconnection.hpp"
#include "localchannel.hpp"

namespace Local_Connection
{
    int _defaultport = 8080;
    class LocalListener : public LocalConnection
    {
    public:
        /**********构造析构************** */
        LocalListener(int port = _defaultport)
            : _port(port),
              _listensock(std::make_unique<Local_Socket::TcpSocket>())
        {
            _listensock->ServerTcpMod(_port);
            // ET mod
            SetEvent(EPOLLIN | EPOLLET);
            SetNonBlock(_listensock->GetFd());
        }
        ~LocalListener() {}

        /**********virtual************** */
        void Recver() override
        {
            Local_Log::LOG(Local_Log::LogLever::LDEBUG) << "LocalListener Recver ";
            // 1.InetAddr
            Local_Inetaddr::Inetaddr lo_inetaddr;
            // 2.Accept
            while (true)
            {
                int lo_sockfd = _listensock->AcceptGetAndCreate(&lo_inetaddr);
                if (lo_sockfd == ACCEPT_ERR || lo_sockfd == ACCEPT_DONE)
                {
                    break;
                }
                else if (lo_sockfd == ACCEPT_CONTINUE)
                {
                    continue;
                }
                else
                {
                    // 3.Add new lo_sockfd -> Local_Reactor::Reactor::_connections;
                    std::shared_ptr<LocalConnection> lo_conn = std::make_shared<LocalChannel>(lo_sockfd, lo_inetaddr);
                    // ET mod
                    lo_conn->SetEvent(EPOLLIN | EPOLLET);
                    if (_handler != nullptr)
                        lo_conn->RegisterHandler(_handler);
                    GetReactor()->AddConnection(lo_conn);
                }
            }
        }
        void Sender() override
        {
            Local_Log::LOG(Local_Log::LogLever::LDEBUG) << "LocalListener Sender ";
        }
        void Excepter() override
        {
            Local_Log::LOG(Local_Log::LogLever::LDEBUG) << "LocalListener Excepter ";
        }
        int GetsockFd() override
        {
            return _listensock->GetFd();
        }

    private:
        int _port;
        std::unique_ptr<Local_Socket::Socket> _listensock;
    };
}